﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;

namespace Douban.Core.Commands
{
    public class EventAdapterBase<T> where T : CommandBehaviorBase<UIElement>
    {
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached("CommandParameter", typeof(object), typeof(EventAdapterBase<T>),
            new UIPropertyMetadata(OnSetCommandParameterCallback));

        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(EventAdapterBase<T>),
            new UIPropertyMetadata(OnSetCommandCallback));

        public static ICommand GetCommand(DependencyObject obj)
        {
            return (ICommand)obj.GetValue(CommandProperty);
        }

        public static void SetCommand(DependencyObject obj, ICommand value)
        {
            obj.SetValue(CommandProperty, value);
        }

        public static object GetCommandParameter(DependencyObject obj)
        {
            return (object)obj.GetValue(CommandParameterProperty);
        }

        public static void SetCommandParameter(DependencyObject obj, object value)
        {
            obj.SetValue(CommandParameterProperty, value);
        }

        private static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            UIElement target = dependencyObject as UIElement;

            if (target == null)
                throw new InvalidCastException("Command target is not an UIElement");

            T behavior = CommandBehaviorFactory.GetOrCreateBehavior<T>(target);
            behavior.Command = e.NewValue as ICommand;
        }

        private static void OnSetCommandParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
        {
            UIElement target = dependencyObject as UIElement;
            if (target != null)
            {
                T behavior = CommandBehaviorFactory.GetOrCreateBehavior<T>(target);
                behavior.CommandParameter = e.NewValue;
            }
        }
    }
}
